package com.naiterui.ehp.bs.ds.modules.order.controller;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.google.common.collect.Sets;
import com.naiterui.ehp.bp.bo.b2c.OrderDeliveryBO;
import com.naiterui.ehp.bp.constants.SwaggerTag;
import com.naiterui.ehp.bp.security.annotation.SysLog;
import com.naiterui.ehp.bp.security.utils.SecurityUtils;
import com.naiterui.ehp.bp.support.advice.IgnoreResponseEntityWrap;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.utils.FileUtil;
import com.naiterui.ehp.bs.ds.common.controller.AbstractController;
import com.naiterui.ehp.bs.ds.common.utils.JwtUser;
import com.naiterui.ehp.bs.ds.common.utils.PageVO;
import com.naiterui.ehp.bs.ds.common.vo.PageParamsVO;
import com.naiterui.ehp.bs.ds.modules.order.feign.IOrderFeignClient;
import com.naiterui.ehp.bs.ds.modules.order.service.IOrderService;
import com.naiterui.ehp.bs.ds.modules.order.vo.LogisticsCompanyVO;
import com.naiterui.ehp.bs.ds.modules.order.vo.OrderDetailVO;
import com.naiterui.ehp.bs.ds.modules.order.vo.OrderVO;
import com.naiterui.ehp.bs.ds.modules.order.vo.PrintOrderDetailVO;
import com.naiterui.ehp.bs.ds.modules.order.vo.StatisticalVO;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 订单管理
 */
@Slf4j
@Validated
@Api(tags = {SwaggerTag.DS + SwaggerTag.ORDER})
@RestController
@AllArgsConstructor
@RequestMapping("order")
public class OrderController extends AbstractController {

  private final IOrderService orderService;
  private final IOrderFeignClient orderFeignClient;

  /**
   * 列表
   *
   * @return
   */
  @SysLog("订单列表")
  @GetMapping("/list")
  @ApiOperation("订单列表")
  @PreAuthorize("@p.check('order:list')")
  public PageVO<OrderVO> list(PageParamsVO pageParamsVO, OrderVO order) {
    return this.orderService.queryPage(pageParamsVO, order);
  }

  @GetMapping("/export")
  @ApiOperation("导出订单")
  @IgnoreResponseEntityWrap
  @PreAuthorize("@p.check('order:export')")
  public void exportOrder(PageParamsVO pageParamsVO, OrderVO order, HttpServletResponse response) throws IOException {
    byte[] body = this.orderService.exportOrder(pageParamsVO, order);
    String fileName = System.getProperty("java.io.tmpdir") + File.separator + System.currentTimeMillis() + ".xls";
    FileUtil.downloadFile(this.request, response, FileUtil.writeBytes(body, fileName), true);
  }

  @SysLog("订单详情")
  @GetMapping("/details/{orderId}")
  @ApiOperation("订单详情")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "long")
  })
  @PreAuthorize("@p.check('order:details')")
  public OrderDetailVO details(@PathVariable("orderId") Long orderId) {
    return this.orderService.getOrderDetails(orderId);
  }

  @SysLog("打印面单")
  @GetMapping("/print/{orderId}")
  @ApiOperation("打印面单")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "long")
  })
  @PreAuthorize("@p.check('order:print')")
  public PrintOrderDetailVO printOrder(@PathVariable("orderId") Long orderId) {
    return this.orderService.printOrder(orderId);
  }

  @SysLog("批量确认/批量拒绝")
  @PostMapping("/confirm/{status}")
  @ApiOperation("批量确认/批量拒绝")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "status", value = "0：确认  1：拒绝", paramType = "path", dataType = "int")
  })
  @PreAuthorize("@p.check('order:confirm')")
  public void warehouseConfirmOrder(@PathVariable("status") Integer status, @RequestBody Set<Long> orderIds) throws BusinessException {
    JwtUser currentUser = SecurityUtils.getCurrentUser();
    this.orderFeignClient.warehouseConfirmOrder(currentUser.getWarehouseId(), orderIds, status);
  }

  @SysLog("订单发货")
  @ApiOperation("订单发货")
  @PreAuthorize("@p.check('order:delivery')")
  @GetMapping("/delivery/{orderId}/{expressId}/{deliveryId}")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "int"),
      @ApiImplicitParam(name = "expressId", value = "快递公司ID", paramType = "path", dataType = "string"),
      @ApiImplicitParam(name = "deliveryId", value = "快递单号", paramType = "path", dataType = "string"),
  })
  public void delivery(@PathVariable Long orderId, @PathVariable Long expressId, @PathVariable String deliveryId) throws BusinessException {
    OrderDeliveryBO delivery = new OrderDeliveryBO();
    delivery.setOrderId(orderId);
    delivery.setExpressId(expressId);
    delivery.setDeliveryId(deliveryId);
    JwtUser currentUser = SecurityUtils.getCurrentUser();
    this.orderFeignClient.delivery(currentUser.getWarehouseId(), Sets.newHashSet(delivery));
  }

  @PostMapping
  @ApiOperation("批量发货")
  @PreAuthorize("@p.check('order:delivery')")
  public void deliveryFile(MultipartFile file) throws BusinessException {
    log.info("批量发货");
    this.orderService.deliveryFile(file);
  }

  /**
   * 统计数据
   *
   * @return
   */
  @SysLog("获取统计数据")
  @ApiOperation("获取统计数据")
  @GetMapping("/statistical")
  @PreAuthorize("@p.check('order:statistical:list')")
  public StatisticalVO statistical() {
    log.info("获取统计数据");
    return this.orderService.getStatisticalVO();
  }

  /**
   * 商品信息
   *
   * @return
   */
  @SysLog("获取快递公司")
  @ApiOperation("获取快递公司")
  @GetMapping("/logistics/company")
  public List<LogisticsCompanyVO> logisticsCompanyList() {
    log.info("获取快递公司");
    return this.orderService.logisticsCompanyList();
  }

  /**
   * 订单提示
   *
   * @return
   */
  @SysLog("订单提示")
  @ApiOperation("订单提示")
  @GetMapping("/tip")
  public Boolean tip() {
    log.info("订单提示");
    return this.orderService.tip();
  }

}
